package org.jsets.fastboot.oss.service.impl;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;
import org.jsets.fastboot.oss.model.entity.FileMeta;
import org.jsets.fastboot.oss.model.entity.Storage;
import org.jsets.fastboot.oss.service.IStorageEngineService;
import org.jsets.fastboot.util.FileUtils;
import org.springframework.util.FileCopyUtils;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;

/**
 * 
 * 本地文件系统
 * 
 * @author wangjie
 *
 */
@Slf4j
public class LocalStorageService implements IStorageEngineService {

	private final Storage config;

	public LocalStorageService(Storage config) {
		this.config = config;
	}
	
	@Override
	public void initialize() {
		FileUtils.mkdirIfNecessary(this.config.getLocalPath());
        File f = new File(this.getLocalPath());
        if(!f.exists()) {
        	f = null;
            throw new RuntimeException("无法创建存储目录["+this.getLocalPath()+"]");
        }
        f = null;
	}
	
	@Override
	public void makeBucket(String bucket) {
		FileUtils.mkdirIfNecessary(FileUtils.pathJoin(this.getLocalPath(), bucket));
	}
	
	@Override
	public void removeBucket(String bucket) {
		FileUtils.removeIfNecessary(FileUtils.pathJoin(this.getLocalPath(), bucket));
	}

	@Override
	public List<String> listBuckets() {
		List<String> result = Lists.newArrayList();
		File file = new File(this.getLocalPath());
		File[] tempList = file.listFiles();
		for (int i = 0; i < tempList.length; i++) {
			if (tempList[i].isDirectory()) {
				result.add(tempList[i].getName());
			}
		}
		return result;
	}

	@Override
	public void upload(FileMeta metadata, InputStream inputStream) {
		try{
			FileUtils.mkdirIfNecessary(this.getLocalPath());
			String fileName = String.valueOf(metadata.getId())+"."+metadata.getExtension();
			String filePath = FileUtils.pathJoin(this.getLocalPath(), metadata.getBucketName(), fileName);
			FileOutputStream out = new FileOutputStream(filePath);
			FileCopyUtils.copy(inputStream, out);
		}catch (Exception e) {
			throw new RuntimeException(e.getMessage(), e);
		}
	}

	@Override
	public void upload(FileMeta metadata, byte[] data) {
		try{
			FileUtils.mkdirIfNecessary(this.getLocalPath());
			String fileName = String.valueOf(metadata.getId())+"."+metadata.getExtension();
			String filePath = FileUtils.pathJoin(this.getLocalPath(), metadata.getBucketName(), fileName);
			FileOutputStream out = new FileOutputStream(filePath);
			FileCopyUtils.copy(data, out);
		}catch (Exception e) {
			throw new RuntimeException(e.getMessage(), e);
		}
	}

	@Override
	public void remove(FileMeta metadata) {
		String fileName = String.valueOf(metadata.getId())+"."+metadata.getExtension();
		String filePath = FileUtils.pathJoin(this.getLocalPath(), metadata.getBucketName(), fileName);
		try {
			Files.delete(Paths.get(filePath));
		} catch (IOException e) {
			log.error(e.getMessage(), e);
		}
	}

	@Override
	public InputStream download(FileMeta metadata) {
		try{
			String fileName = String.valueOf(metadata.getId())+"."+metadata.getExtension();
			String filePath = FileUtils.pathJoin(this.getLocalPath(), metadata.getBucketName(), fileName);
			File in = new File(filePath);
			return new FileInputStream(in);
		}catch (Exception e) {
			throw new RuntimeException(e.getMessage(), e);
		}
	}
	
	@Override
	public void close() {
	}
	
	private String getLocalPath() {
		return this.config.getLocalPath();
	}
}